import testCafeCore from '../../deps/testcafe-core';

const domUtils        = testCafeCore.domUtils;
const contentEditable = testCafeCore.contentEditable;


function getSelectTextAreaContentArguments (element, argumentsObject) {
    const value         = domUtils.getTextAreaValue(element);
    const linesArray    = value && value.length ? value.split('\n') : [];
    const lastLineIndex = linesArray.length - 1;

    const startLineIndex  = !argumentsObject.startLine ? 0 : Math.min(argumentsObject.startLine, lastLineIndex);
    const startLineLength = linesArray[startLineIndex] ? linesArray[startLineIndex].length : 0;
    const startPos        = !argumentsObject.startPos ? 0 : Math.min(argumentsObject.startPos, startLineLength);

    const endLineIndex = argumentsObject.endLine === void 0 || argumentsObject.endLine === null ?
        lastLineIndex : Math.min(argumentsObject.endLine, lastLineIndex);

    const endLineLength = linesArray[endLineIndex] ? linesArray[endLineIndex].length : 0;
    const endPos        = argumentsObject.endPos === void 0 ||
                        argumentsObject.endPos ===
                        null ? endLineLength : Math.min(argumentsObject.endPos, endLineLength);

    const startLinePosition = domUtils.getTextareaPositionByLineAndOffset(element, startLineIndex, 0);
    const endLinePosition   = domUtils.getTextareaPositionByLineAndOffset(element, endLineIndex, 0);

    return {
        startPos: startLinePosition + startPos,
        endPos:   endLinePosition + endPos,
    };
}

export default function (element, argumentsObject = {}) {
    const isTextEditable = domUtils.isTextEditableElement(element);
    const firstPos       = isTextEditable ? 0 : contentEditable.getFirstVisiblePosition(element);
    const lastPos        = isTextEditable ? domUtils.getElementValue(element).length : contentEditable.getLastVisiblePosition(element);
    let startPos       = !argumentsObject.startPos ? firstPos : Math.min(argumentsObject.startPos, lastPos);
    let endPos         = argumentsObject.endPos === void 0 ||
                         argumentsObject.endPos === null ? lastPos : Math.min(argumentsObject.endPos, lastPos);

    if (argumentsObject.offset !== void 0) {
        if (argumentsObject.offset >= 0)
            endPos = Math.min(argumentsObject.offset, endPos);
        else {
            startPos = endPos;
            endPos   = Math.max(0, endPos + argumentsObject.offset);
        }

        return { startPos, endPos };
    }

    if (argumentsObject.startLine !== void 0)
        return getSelectTextAreaContentArguments(element, argumentsObject);

    return { startPos, endPos };
}
